<script setup>
import Map from "ol/Map.js";
import View from "ol/View.js";
import TileLayer from "ol/layer/Tile.js";
import { onMounted, reactive, ref } from "vue";
import { XYZ } from "ol/source";
import { Feature } from "ol";
import Point from "ol/geom/Point.js";
import { Style, Icon, Stroke, Fill, Text, Circle } from "ol/style";
import VectorSource from "ol/source/Vector.js";
import VectorLayer from "ol/layer/Vector.js";
import { fromLonLat, toLonLat, transform } from "ol/proj";
import LineString from "ol/geom/LineString.js";
import Polygon from "ol/geom/Polygon.js";

import blue from "../../assets/blue.png";
import VScaleScreen from 'v-scale-screen'

const mapVal = ref(null);
const features = reactive({
  point: {
    features: null,
    source: null,
    vector: null,
    disabled_val: false,
  },
  line: {
    features: null,
    source: null,
    vector: null,
    disabled_val: false,
  },
  area: {
    features: null,
    source: null,
    vector: null,
    disabled_val: false,
  },
  pic: {
    features: null,
    source: null,
    vector: null,
    disabled_val: false,
  },
  text: {
    features: null,
    source: null,
    vector: null,
    disabled_val: false,
  },
});
onMounted(() => {
  initMap();
});

// 初始化地图
const initMap = () => {
  mapVal.value = new Map({
    view: new View({
      center: [116.403, 39.924],
      zoom: 1,
      minZoom: 2,
      maxZoom: 20,
      projection: "EPSG:4326",
      constrainResolution: true, // 设置缩放级别为整数
      smoothResolutionConstraint: false, // 关闭无级缩放地图
    }),
    layers: [
      new TileLayer({
        source: new XYZ({
          url: "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}",
        }),
      }),
    ],

    target: "map",
  });
};

// 添加点
const addPoint = () => {

  features.point.features = new Feature({
    geometry: new Point(
      fromLonLat([111.7277312, 40.8143503], "EPSG:4326", "EPSG:3857")
    ),
  });
  features.point.features.setStyle(
    new Style({
      //填充色
      fill: new Fill({
        color: "red",
      }),
      //边线颜色
      stroke: new Stroke({
        color: "red",
        width: 5,
      }),
      //形状
      image: new Circle({
        radius: 5,
        fill: new Fill({
          color: "red",
        }),
      }),
    })
  );
  //实例化一个矢量图层Vector作为绘制层
  //  features.point.source = new VectorSource({
  //    features: [features.point.features],
  //  });
  var source = new VectorSource()
  source.addFeature(features.point.features)
  //创建一个图层
  var layer = new VectorLayer({
    source: source
  })

  mapVal.value.addLayer(layer);
  features.point.disabled_val = true;
};

//add point 添加点  新方法
const newAddPoint = () => {
  // 1、在地图上创建一个要素源
  var source = new VectorSource();

  // 2、点位坐标
  var coordinates = [[111.7277112, 40.8143503], [111.7277212, 40.8143503], [111.7277312, 40.8143503]]; // 要添加的点的坐标

  // 3、遍历添加点
  coordinates.forEach(i => {
    let point = new Point(fromLonLat(i, "EPSG:4326", "EPSG:3857"))
    let feature = new Feature(point)
    // 设置点的样式
    feature.setStyle(new Style({
      //填充色
      fill: new Fill({
        color: "red",
      }),
      //边线颜色
      stroke: new Stroke({
        color: "red",
        width: 5,
      }),
      //形状
      image: new Circle({
        radius: 5,
        fill: new Fill({
          color: "red",
        }),
      }),
    }))
    
    source.addFeature(feature)
  });
  var layer = new VectorLayer({
    source: source
  })

  mapVal.value.addLayer(layer);
  features.point.disabled_val = true;

}

// 添加线
const addLine = () => {
  //创建一个线
  features.line.features = new Feature({
    geometry: new LineString([
      fromLonLat([111.7082293, 40.8092789], "EPSG:4326", "EPSG:3857"),
      fromLonLat([111.7061345, 40.8141626], "EPSG:4326", "EPSG:3857"),
    ]),
  });

  //设置线的样式
  features.line.features.setStyle(
    new Style({
      //填充色
      fill: new Fill({
        color: "rgba(255, 255, 255, 0.2)",
      }),
      //边线颜色
      stroke: new Stroke({
        color: "red",
        width: 5,
      }),
      //形状
      image: new Circle({
        radius: 7,
        fill: new Fill({
          color: "red",
        }),
      }),
    })
  );

  //实例化一个矢量图层Vector作为绘制层
  features.line.source = new VectorSource({
    features: [features.line.features],
  });
  //创建一个图层
  features.line.vector = new VectorLayer({
    source: features.line.source,
  });
  //将绘制层添加到地图容器中
  mapVal.value.addLayer(features.line.vector);
  features.line.disabled_val = true;
};

// 添加区域
const addArea = () => {
  //根据范围获取多边形
  features.area.features = new Feature({
    geometry: new Polygon([
      [
        [111.69836189830245, 40.82563352874919],
        [111.70059350148688, 40.795596650207465],
        [111.72891762925963, 40.79743376790391],
        [111.72763016890633, 40.824071970998354],
        [111.71338226909104, 40.82673580006786],
        [111.69836189830245, 40.82563352874919],
      ],
    ]),
  });

  features.area.features.setStyle(
    new Style({
      fill: new Fill({
        color: "rgba(0,0,0,0.5)",
      }),
      stroke: new Stroke({
        color: "#ffcc33",
        width: 2,
      }),
      image: new Circle({
        radius: 7,
        fill: new Fill({
          color: "#ffcc33",
        }),
      }),
    })
  );

  //实例化一个矢量图层Vector作为绘制层
  features.area.source = new VectorSource({
    features: [features.area.features],
  });
  //创建一个图层
  features.area.vector = new VectorLayer({
    source: features.area.source,
  });
  //将绘制层添加到地图容器中
  mapVal.value.addLayer(features.area.vector);
  features.area.disabled_val = true;
};

// 跳转到某个点
const toPoint = () => {
  //这里给动画设置一个初始值
  mapVal.value.getView().animate({
    //将地理坐标转为投影坐标
    center: fromLonLat([111.7277312, 40.8143503], "EPSG:4326", "EPSG:3857"),
    duration: 1000,
    zoom: 12,
    rotation: 6,
  });
};

// 添加标注
const addPic = () => {
  var createLabelStyle = function (feature) {
    return new Style({
      /**{olx.style.IconOptions}类型*/
      image: new Icon({
        anchor: [0.5, 0.5],
        // anchorOrigin: "top-right",
        // anchorXUnits: "fraction",
        // anchorYUnits: "pixels",
        // offsetOrigin: "top-right",
        // offset:[0,10],
        //图标缩放比例
        // scale:0.5,
        //透明度
        // opacity: 1,
        //图标的url
        src: blue,
      }),
    });
  };
  //实例化Vector要素，通过矢量图层添加到地图容器中
  features.pic.features = new Feature({
    // geometry: new ol.geom.Point(ol.proj.transform([116.403, 39.924], 'EPSG:4326', 'EPSG:3857')),
    geometry: new Point(
      fromLonLat([111.7113801, 40.8236402], "EPSG:4326", "EPSG:3857")
    ),
  });

  features.pic.features.setStyle(createLabelStyle(features.pic.features));
  //矢量标注的数据源
  features.pic.source = new VectorSource({
    features: [features.pic.features],
  });
  //矢量标注图层
  features.pic.vector = new VectorLayer({
    source: features.pic.source,
  });
  mapVal.value.addLayer(features.pic.vector);
  features.pic.disabled_val = true;
};

// 文字标注
const addText = () => {
  // /**
  //  * 创建矢量标注样式函数,设置image为图标ol.style.Icon
  //  * @param {ol.Feature} feature 要素
  //  */
  var createLabelStyle = function (feature) {
    return new Style({
      text: new Text({
        //位置
        textAlign: "center",
        //基准线
        textBaseline: "middle",
        //文字样式
        font: "normal 14px 微软雅黑",
        //文本内容
        text: feature.get("name"),
        //文本填充样式（即文字颜色）
        fill: new Fill({ color: "red" }),
        stroke: new Stroke({ color: "#ffcc33", width: 4 }),
      }),
    });
  };

  //实例化Vector要素，通过矢量图层添加到地图容器中
  features.text.features = new Feature({
    geometry: new Point(
      fromLonLat([111.7111116, 40.8030263], "EPSG:4326", "EPSG:3857")
    ),
    //名称属性
    name: "呼和浩特",
    //大概人口数（万）
    population: 2115,
  });
  features.text.features.setStyle(createLabelStyle(features.text.features));
  //矢量标注的数据源
  features.text.source = new VectorSource({
    features: [features.text.features],
  });
  //矢量标注图层
  features.text.vector = new VectorLayer({
    source: features.text.source,
  });
  mapVal.value.addLayer(features.text.vector);
  features.text.disabled_val = true;
};
// 删除
const deleteChange = () => {
  for (let i in features) {
    // 移除源
    if (features[i].source) {
      features[i].source.clear();
    }
    if (features[i].features) {
      // 清空样式
      features[i].features.setStyle(null);
    }
    if (features[i].disabled_val) {
      features[i].disabled_val = false;
    }
    // 移除图层
    mapVal.value.removeLayer(features[i].vector);
  }
};
</script>

<template>
  <v-scale-screen style="background: '#AAD3F2 !important;" :width="2560" :height="1440" :fullScreen="true" :delay="100">
    <div class="flex-center" style="flex-direction: column; align-items: center;">
      <div class="flex-center">
        <el-button @click="newAddPoint" :disabled="features.point.disabled_val">添加点</el-button>
        <el-button @click="addLine" :disabled="features.line.disabled_val">添加线</el-button>
        <el-button @click="addArea" :disabled="features.area.disabled_val">添加面</el-button>
        <el-button @click="toPoint">跳转点</el-button>
        <el-button @click="addPic" :disabled="features.pic.disabled_val">添加标注</el-button>
        <el-button @click="addText" :disabled="features.text.disabled_val">添加文字标注</el-button>
        <el-button type="danger" @click="deleteChange">清除</el-button>
      </div>
      <div id="map" style="width: 100vw; height: 100vh;"></div>
    </div>
  </v-scale-screen>
</template>
<style scoped>
.flex-center {
  display: flex;
  justify-content: center;
  margin-bottom: 10px;
}
</style>